import { Message, Switch, Tabs } from '@arco-design/web-react'
import {
    closestCenter,
    DndContext,
    DragEndEvent,
    KeyboardSensor,
    PointerSensor,
    useSensor,
    useSensors,
} from '@dnd-kit/core'
import {
    horizontalListSortingStrategy,
    SortableContext,
    sortableKeyboardCoordinates,
    useSortable,
} from '@dnd-kit/sortable'
import classNames from 'classnames'
import React, { useState } from 'react'
import { IGroupItem, IListItem } from '../../../../utils/interfaces'
import { apiStore } from '../../../../utils/store/apiStore'
import { enableSorter } from './useGroup'
import { useStorageState } from '../../hooks/useStorageState'

const { TabPane } = Tabs

// TabTitle 组件的 Props
interface TabTitleProps {
    item: IGroupItem
    handleGroupChange: (item: IListItem, enabled: boolean) => void
}

// TabPane 的 Title 组件（支持拖拽）
const TabTitle: React.FC<TabTitleProps> = ({ item, handleGroupChange }) => {
    // useSortable hook 提供拖拽能力
    const {
        attributes,
        listeners,
        setNodeRef,
        transform,
        transition,
        isDragging,
    } = useSortable({ id: item.id })

    const style = {
        transform: transform
            ? `translate3d(${transform.x}px, ${transform.y}px, 0)`
            : undefined,
        transition,
        opacity: isDragging ? 0.5 : 1,
        cursor: isDragging ? 'grabbing' : 'grab',
    }

    return (
        <div
            ref={setNodeRef}
            style={style}
            className={isDragging ? 'dragging-tab' : ''}
            {...attributes}
            {...listeners}
        >
            {item.label}
            <Switch
                checked={item.enabled}
                onChange={(v, e) => {
                    e.stopPropagation()
                    handleGroupChange(item, v)
                }}
                size='small'
                className='ml-2'
            />
        </div>
    )
}

export interface IGroupTabsProps {
    // 类名
    className?: string
    // 选中的组变化
    onSelectedGroupChange?: (groupId: string) => void
}

const GroupTabs: React.FC<IGroupTabsProps> = ({
    onSelectedGroupChange,
    className,
}) => {
    // tab数据
    const [groupData, setGroupData] = useState<IGroupItem[][]>([])
    // 被选中的
    const [selectedIds, setSelectedIds] = useStorageState(
        'groupTabsSelectedIds',
        {
            defaultValue: [''],
            afterInit: (value) => {
                updateGroupData(value)
                const selected = value[value.length - 1]
                if (selected) {
                    onSelectedGroupChange?.(selected)
                }
            },
        },
    )
    // 正在拖拽的 item id
    const [draggingId, setDraggingId] = useState<string | null>(null)

    // 配置拖拽传感器
    const sensors = useSensors(
        useSensor(PointerSensor, {
            activationConstraint: {
                distance: 8, // 移动8px后才开始拖拽，避免误触
            },
        }),
        useSensor(KeyboardSensor, {
            coordinateGetter: sortableKeyboardCoordinates,
        }),
    )

    // 初始化
    const initGroupData = async () => {
        setSelectedIds([''])
        queryGroupItems().then((items) => {
            setGroupData([items])
        })
        onSelectedGroupChange?.('')
    }

    // 筛选
    const filterGroupItems = (
        list: IListItem[],
        parentId?: string,
    ): IGroupItem[] => {
        let filtered = []
        if (parentId) {
            filtered = list.filter(
                (v) => v.parentId === parentId && v.type === 'group',
            )
        } else {
            filtered = list.filter((v) => !v.parentId && v.type === 'group')
        }
        return filtered as IGroupItem[]
    }

    // 更新组数据
    const updateGroupData = async (ids: string[] = selectedIds) => {
        const list = await apiStore.getAllList()
        const groupData: IGroupItem[][] = [
            filterGroupItems(list) as IGroupItem[],
        ]
        for (let i = 0; i < ids.length - 1; i++) {
            const id = ids[i]
            const items = filterGroupItems(list, id)
            groupData.push(items as IGroupItem[])
        }
        setGroupData(groupData)
    }

    // 更改enabled
    const handleGroupChange = async (item: IListItem, enabled: boolean) => {
        const cloned = { ...item }
        cloned.enabled = enabled
        await apiStore.save(cloned)
        Message.success({
            content: '操作成功',
            position: 'bottom',
        })
        updateGroupData()
    }

    // 查询某个分组下的所有组
    const queryGroupItems = async (parentId?: string) => {
        const list = await apiStore.getList(parentId)
        const groupItems = filterGroupItems(list, parentId)
        return groupItems
    }

    // 选中的tab变化
    const handleActiveTabChange = async (id: string, index: number) => {
        if (index === 0 && !id) {
            initGroupData()
            return
        }

        // 设置当前选中的id
        const newSelectedIds = selectedIds.slice(0, index + 1)
        newSelectedIds[index] = id
        // 组列表
        const newGroupData = groupData.slice(0, index + 1)
        // 如果不是选中的上一级tab，也就我在第
        if (newSelectedIds[index - 1] !== id) {
            newSelectedIds.push(id)
            const groupDataLine = await queryGroupItems(id)
            newGroupData.push(groupDataLine)
        }
        // 更新state
        setSelectedIds(newSelectedIds)
        setGroupData(newGroupData)
        // 更新列表
        onSelectedGroupChange?.(id)
    }

    // 处理拖拽开始
    const handleDragStart = (event: DragEndEvent) => {
        setDraggingId(event.active.id as string)
    }

    // 处理拖拽结束
    const handleDragEnd = async (event: DragEndEvent, levelIndex: number) => {
        const { active, over } = event

        // 清除拖拽状态
        setDraggingId(null)

        if (!over || active.id === over.id) {
            return
        }

        // 更新 store
        try {
            await apiStore.moveItem(active.id as string, over.id as string)
            // 重新从 store 加载数据
            await updateGroupData(selectedIds)
        } catch (error) {
            console.error('移动失败:', error)
        }
    }

    return (
        <>
            <div className={classNames('tabs-container', className)}>
                {groupData?.map((groupItems, index) => {
                    const selectedGroupId = selectedIds?.[index] || ''

                    if (!groupItems?.length || groupItems.length < 1) {
                        return null
                    }

                    return (
                        <div className='w-full'>
                            <DndContext
                                key={selectedGroupId + index}
                                sensors={sensors}
                                collisionDetection={closestCenter}
                                onDragStart={handleDragStart}
                                onDragEnd={(event) =>
                                    handleDragEnd(event, index)
                                }
                            >
                                <SortableContext
                                    items={groupItems.map((item) => item.id)}
                                    strategy={horizontalListSortingStrategy}
                                >
                                    <Tabs
                                        className='mb-1'
                                        type='rounded'
                                        activeTab={selectedIds?.[index]}
                                        onChange={(id) =>
                                            handleActiveTabChange(id, index)
                                        }
                                        size='mini'
                                        renderTabTitle={(tabTitle) => {
                                            // 使用 React.cloneElement 创建新元素，避免修改只读 props
                                            const element =
                                                tabTitle as React.ReactElement<any>
                                            const currentClassName =
                                                element.props?.className || ''

                                            // 只要有拖拽发生，所有 tab 都添加透明背景
                                            const hasDragging =
                                                draggingId !== null

                                            return React.cloneElement(element, {
                                                ...element.props,
                                                className: hasDragging
                                                    ? `${currentClassName} !bg-transparent`
                                                    : currentClassName,
                                            })
                                        }}
                                    >
                                        <TabPane
                                            key={selectedIds?.[index - 1] || ''}
                                            title={
                                                <span className='mx-1'>/</span>
                                            }
                                        />
                                        {groupItems?.map((item) => {
                                            return (
                                                <TabPane
                                                    key={item.id}
                                                    title={
                                                        <TabTitle
                                                            item={item}
                                                            handleGroupChange={
                                                                handleGroupChange
                                                            }
                                                        />
                                                    }
                                                />
                                            )
                                        })}
                                    </Tabs>
                                </SortableContext>
                            </DndContext>
                        </div>
                    )
                })}
            </div>
        </>
    )
}

export default GroupTabs
